#include <math.h>
#include "FPSCamera.hpp"

#ifndef M_PI
# define M_PI   3.1415926535323846
#endif

FPSCamera::FPSCamera():
    Camera(),
    _forward(0, 0, 0),
    _left(0, 0, 0),
    _theta(45),
    _phi(-10),
    _speed(0.01),
    _sensivity(0.1)
{
    computeVectors();
}

FPSCamera::FPSCamera(Vec3f const& position, Vec3f const& lookedPoint, Vec3f const& orientation):
    Camera(position, lookedPoint, orientation),
    _forward(0, 0, 0),
    _left(0, 0, 0),
    _theta(45),
    _phi(-10),
    _speed(0.01),
    _sensivity(0.1)
{
    computeVectors();
}

Vec3f const&    FPSCamera::getForward() const
{
    return _forward;
}

void            FPSCamera::setForward(Vec3f const& forward)
{
    _forward = forward;
}

void            FPSCamera::setForward(float x, float y, float z)
{
    _forward.set(x, y, z);
}

Vec3f const&    FPSCamera::getLeft() const
{
    return _left;
}

void            FPSCamera::setLeft(Vec3f const& left)
{
    _left = left;
}

void            FPSCamera::setLeft(float x, float y, float z)
{
    _left.set(x, y, z);
}

float           FPSCamera::getTheta() const
{
    return _theta;
}

void            FPSCamera::setTheta(const float theta)
{
    _theta = theta;
}

float           FPSCamera::getPhi() const
{
    return _phi;
}

void            FPSCamera::setPhi(const float phi)
{
    _phi = phi;
}

float           FPSCamera::getSpeed() const
{
    return _speed;
}

void            FPSCamera::setSpeed(const float speed)
{
    _speed = speed;
}

float           FPSCamera::getSensivity() const
{
    return _sensivity;
}

void            FPSCamera::setSensivity(const float sensivity)
{
    _sensivity = sensivity;
}

void            FPSCamera::computeVectors()
{
    if (_phi < -89.f)
        _phi = -89.f;
    else if (_phi > 89.f)
        _phi = 89.f;

    float       x, y, z;
    float       rTemp = cos(_phi * M_PI / 180.f);

    x = rTemp * cos(_theta * M_PI / 180.f);
    y = sin(_phi * M_PI / 180.f);
    z = rTemp * sin(_theta * M_PI / 180.f);

    _forward.set(x, y, z);

    _left = _orientation.prodVec(_forward);
    _left.normalize();

    _lookedPoint = _position + _forward;
}

void            FPSCamera::moveForward(int elapsedTime)
{
    _position = _position + _forward * _speed * elapsedTime;
    _lookedPoint = _position + _forward;
}

void            FPSCamera::moveBackward(int elapsedTime)
{
    _position = _position - _forward * _speed * elapsedTime;
    _lookedPoint = _position + _forward;
}

void            FPSCamera::moveLeft(int elapsedTime)
{
    _position = _position - _left * _speed * elapsedTime;
    _lookedPoint = _position + _forward;
}

void            FPSCamera::moveRight(int elapsedTime)
{
    _position = _position + _left * _speed * elapsedTime;
    _lookedPoint = _position + _forward;
}
